package com.ilia.util.set;

import java.util.ArrayList;
import java.util.List;

public class BitUtils {

  public static int EVAL_BIT_LENGTH = 63;
  
  public static void main(String[] argv) {
    long[] bits = computeBinaryField(10, new int[]{0,1});
    int[] rec = computeRecords(bits);
    bits = computeBinaryField(100, new int[]{61,62});
    rec = computeRecords(bits);
    bits = computeBinaryField(10, new int[]{0,1,2});
    rec = computeRecords(bits);
    bits = computeBinaryField(100, new int[]{62});
    rec = computeRecords(bits);
    
  }
  
  
  public static int[] computeRecords(long[] bits) {
    List<Integer> c_plus = new ArrayList<Integer>();
    int currLongIndex = -1;
      long currBitIndex = 0;
      for (int i = 0; i < bits.length*EVAL_BIT_LENGTH; i++) {
        if (currBitIndex==0) {
          currLongIndex++;
          currBitIndex=1l<<(EVAL_BIT_LENGTH-1);
        }

        int value = (bits[currLongIndex]&currBitIndex)>0?1:0;
        if (value==1) {
          c_plus.add(i);
        }
        currBitIndex = currBitIndex>>1;
    }
    int[] records = new int[c_plus.size()];
    int k = 0;
    for (int i : c_plus) {
      records[k] = i;
      k++;
    }
    return records;

  }
  
  
  public static long[] orBinaryField(long[] bitsA, long[] bitsB) {
    long[] bin = new long[bitsA.length];
    for (int i =0;i<bin.length;i++) {
      bin[i] = bitsA[i] | bitsB[i];
    }
    return bin;
  }

	public static long[] xorBinaryField(long[] bitsA, long[] bitsB) {
		long[] bin = new long[bitsA.length];
		for (int i = 0; i < bin.length; i++) {
			bin[i] = bitsA[i] ^ bitsB[i];
		}
		return bin;
	}  
  
  public static boolean isOverlapping(long[] bitsA, long[] bitsB) {
    for (int i =0;i<bitsA.length;i++) {
      long x = bitsA[i] & bitsB[i];
      if (x!=0) return true;
    }
    return false;
  }

  
  
  public static long[] computeBinaryField(int num_records, int[] records) {
      int longs = num_records / EVAL_BIT_LENGTH;
      if (longs*EVAL_BIT_LENGTH<num_records) {
        longs++;
      }
      long[] binPlus = new long[longs];
      int[] c_plus = new int[num_records];
      for (int i : records) {
      c_plus[i] = 1;
    }
      int currLongIndex = 0;
      int currBitIndex = 0;
    long a_plus_long = 0;
      for (int i = 0; i < c_plus.length; i++) {
        if (currBitIndex==EVAL_BIT_LENGTH) {
          binPlus[currLongIndex] = a_plus_long;
          currLongIndex++;
          currBitIndex=0;
          a_plus_long = 0;
        }
        int a_plus = c_plus[i];
        a_plus_long = (a_plus_long<<1) | a_plus;
        currBitIndex++;
    }
      if (currBitIndex!=0) {
        while (currBitIndex!=EVAL_BIT_LENGTH) {
            a_plus_long = (a_plus_long<<1);
            currBitIndex++; 
        }
        binPlus[currLongIndex] = a_plus_long;
      }
      return binPlus;
    }
}
